"""
GitLab数据采集模块
"""
import gitlab
from typing import List, Dict, Optional
from datetime import datetime
import logging

class GitLabCrawler:
    def __init__(self, url: str, private_token: str, project_id: int):
        self.gl = gitlab.Gitlab(url, private_token=private_token)
        self.project = self.gl.projects.get(project_id)
        self.logger = logging.getLogger(__name__)

    def get_commit_history(self, since: Optional[datetime] = None) -> List[Dict]:
        """获取GitLab项目的提交历史
        
        Args:
            since: 可选，获取指定日期之后的提交
            
        Returns:
            List[Dict]: 提交历史列表
        """
        try:
            commits = []
            # 获取所有提交
            for commit in self.project.commits.list(all=True):
                if since and commit.committed_date < since:
                    continue
                    
                commit_data = {
                    'commit_id': commit.id,
                    'author': commit.author_name,
                    'date': commit.committed_date,
                    'message': commit.message,
                    'diff': self._get_commit_diff(commit.id)
                }
                commits.append(commit_data)
                
            return commits
            
        except Exception as e:
            self.logger.error(f"获取GitLab提交历史失败: {str(e)}")
            return []

    def _get_commit_diff(self, commit_id: str) -> Dict:
        """获取某次提交的代码差异
        
        Args:
            commit_id: 提交ID
            
        Returns:
            Dict: 包含文件修改信息的字典
        """
        try:
            commit = self.project.commits.get(commit_id)
            diff_info = {
                'files_changed': [],
                'insertions': 0,
                'deletions': 0
            }
            
            # 获取具体的diff信息
            for change in commit.diff():
                file_diff = {
                    'file_path': change['new_path'],
                    'change_type': self._get_change_type(change),
                    'diff_content': change['diff']
                }
                diff_info['files_changed'].append(file_diff)
                
            return diff_info
            
        except Exception as e:
            self.logger.error(f"获取提交差异失败: {str(e)}")
            return {}

    def _get_change_type(self, change: Dict) -> str:
        """确定文件变更类型"""
        if change['new_file']:
            return 'A'  # Added
        elif change['deleted_file']:
            return 'D'  # Deleted
        elif change['renamed_file']:
            return 'R'  # Renamed
        else:
            return 'M'  # Modified

    def get_merge_requests(self, state: str = 'merged') -> List[Dict]:
        """获取合并请求信息
        
        Args:
            state: 合并请求状态 (merged/opened/closed)
            
        Returns:
            List[Dict]: 合并请求列表
        """
        try:
            mrs = []
            for mr in self.project.mergerequests.list(state=state, all=True):
                mr_data = {
                    'id': mr.iid,
                    'title': mr.title,
                    'description': mr.description,
                    'author': mr.author['name'],
                    'created_at': mr.created_at,
                    'merged_at': mr.merged_at,
                    'source_branch': mr.source_branch,
                    'target_branch': mr.target_branch,
                    'commits': self._get_mr_commits(mr)
                }
                mrs.append(mr_data)
                
            return mrs
            
        except Exception as e:
            self.logger.error(f"获取合并请求失败: {str(e)}")
            return []

    def _get_mr_commits(self, mr) -> List[Dict]:
        """获取合并请求中的提交信息"""
        return [
            {
                'id': commit.id,
                'message': commit.message,
                'author': commit.author_name,
                'date': commit.committed_date
            }
            for commit in mr.commits()
        ] 